package com.block.common.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.block.common.bean.SessionBean;
import com.block.common.constant.RedisKeyConstant;
import com.block.common.enums.LoginStatusEnum;
import com.block.common.model.dto.CommonReqDTO;
import com.block.common.model.dto.LoginReqDTO;
import com.block.common.service.ICountCommonService;
import com.block.common.service.ILoginSessionService;
import com.block.db.entity.LoginSession;
import com.block.db.entity.MemberInfo;
import com.block.db.mapper.LoginSessionMapper;
import com.block.db.mapper.MemberInfoMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * 
 * @since 2021-02-27
 */
@Slf4j
@Service
public class LoginSessionServiceImpl extends ServiceImpl<LoginSessionMapper, LoginSession> implements ILoginSessionService {

    @Resource
    MemberInfoMapper memberInfoMapper;
    @Autowired
    RedisTemplate<String, SessionBean> redisSessionTemplate;
    @Autowired
    ICountCommonService countCommonService;

    @Override
    public SessionBean loginSession(Long uid, LoginReqDTO loginReqDTO, CommonReqDTO commonReqDTO) {

        //查询登录状态的token
        List<LoginSession> sessionList = this.baseMapper.getByUidAndStatusAndTypes(uid, LoginStatusEnum.LOGIN.getValue());
        // 使之前登录的token失效
        if (!CollUtil.isEmpty(sessionList)) {
            sessionList.stream().forEach(memberLoginsession1 -> {
                String expriToken = memberLoginsession1.getToken();
                String tokenKey = RedisKeyConstant.TOKEN_REDIS_KEY_PREFIX.concat(expriToken);
                if (redisSessionTemplate.hasKey(tokenKey)) {
                    redisSessionTemplate.delete(tokenKey);
                }
                memberLoginsession1.setStatus(LoginStatusEnum.EFFECT.getValue());
                memberLoginsession1.setUpdateTime(LocalDateTime.now());
            });
            boolean result = updateBatchById(sessionList, sessionList.size());
            log.info("[批量更新token为失效状态结果]{}", result);
        }

        //登录的session不存在.则创建. 存在且未过期 则更新
        LoginSession loginSession = new LoginSession();
        loginSession.setDateInfo(LocalDate.now().toString());
        loginSession.setStatus(LoginStatusEnum.LOGIN.getValue());
        loginSession.setUid(uid);
        MemberInfo memberInfo = memberInfoMapper.selectById(uid);
        if (memberInfo != null){
            loginSession.setPhoneNo(memberInfo.getMobile());
        }
        loginSession.setLoginType(loginReqDTO.getLoginType());
        loginSession.setReqIp(loginReqDTO.getReqIp());
        loginSession.setLoginDatetime(LocalDateTime.now());
        loginSession.setUpdateTime(LocalDateTime.now());
        loginSession.setStatus(LoginStatusEnum.LOGIN.getValue());
        loginSession.setChannelCode(memberInfo.getChannelCode());
        loginSession.setChannelName(memberInfo.getChannelName());
        loginSession.setReqChannelCode(commonReqDTO.getReqChannelCode());
        loginSession.setReqChannelName(commonReqDTO.getReqChannelName());
        loginSession.setRegDate(memberInfo.getCreateTime().toLocalDate().toString());

//        String token = SnowflakeUtil.getSnowflakeByDate(IdTypeEnum.COMMON, 27);
        String token = UUID.fastUUID().toString(true);

        loginSession.setToken(token);
        boolean saveResult = save(loginSession);
        log.info("[集合数大于1或已经超时 保存session结果]{}", saveResult);

        String tokenKey = RedisKeyConstant.TOKEN_REDIS_KEY_PREFIX.concat(token);
        SessionBean sessionBean = new SessionBean();
        sessionBean.setToken(tokenKey);
        sessionBean.setUid(uid);
        if (memberInfo != null){
            sessionBean.setUsername(memberInfo.getUsername());
            sessionBean.setMobile(memberInfo.getMobile());
            sessionBean.setChannelCode(memberInfo.getChannelCode());
            sessionBean.setChannelName(memberInfo.getChannelName());
            sessionBean.setUserRegDate(memberInfo.getCreateTime().toLocalDate().toString());
            sessionBean.setUserLoginDate(LocalDate.now().toString());
            sessionBean.setAuthFlag(memberInfo.getExtInfoFlag());
            sessionBean.setUserType(memberInfo.getType());
            sessionBean.setZhima(memberInfo.getZhima());
        }

        commonReqDTO.setChannelCode(memberInfo.getChannelCode());
        commonReqDTO.setChannelName(memberInfo.getChannelName());

        // TODO: 2022/7/25 用户登陆token 有效时间
        //存入缓存，永久有效
        redisSessionTemplate.opsForValue().set(tokenKey, sessionBean, 3l, TimeUnit.DAYS);
        return sessionBean;
    }

}
